/**
  ******************************************************************************
  * @文件名           : fml_store.h
  * @作者             : mbl
  * @功能介绍         	: 数据存储算法
  *	@日期             : 2024.06.28
  ******************************************************************************
  * @注意
  *
  *
  *
  ******************************************************************************
  *更改记录
  *日期 修改人 修改内容
  *
  *
  *
  ******************************************************************************
  */

#ifndef INC_FML_STORE_H_
#define INC_FML_STORE_H_
#include <stdint.h>

#define CRC_BIT			2		/* CRC校验位数固定死 */
#define DATA_INDEX_MAX 1024     /* 数据索引数量最大值 默认：1024 */
#define DATA_INDEX_UNIN_SIZE 32 /* 数据索引每个单元的大小 默认：32 */

/* 数据索引单元最大数量 */
#define DATA_INDEX_UNIN_MAX (DATA_INDEX_MAX / DATA_INDEX_UNIN_SIZE)

/* FLASH 错误码 */
typedef enum
{
    FLASH_NO_ERR = 0,			// 操作FALSH没有错误
	FLASH_READ_ERR,				// 读出FALSH错误
	FLASH_WRITE_ERR,			// 写入FALSH错误
	FLASH_CONFIG_ERR
} FLASH_Err_t;

/* 页面状态 */
typedef enum {
    PAGE_NOT_INIT = 0xFF,       // 未初始化，表示页面尚未被初始化
    PAGE_FREE = 0x0F,           // 空，表示页面是空的，没有数据
    PAGE_IN_USE = 0x01,         // 使用中，表示页面正在被使用
    PAGE_FULL_DIRTY = 0x00      // 全满且全脏，表示页面已满且包含脏数据
} PageStatus_t;

/* FLASH 设备 */
typedef struct {
	char *flashName;		     // flash名称
    uint32_t startAddr;          // 起始地址
    uint32_t totalSize;          // 总尺寸
    uint16_t minEraseSize;       // 最小擦除尺寸
    uint16_t minOperateSize;     // 最小操作尺寸
    void (*initFlashCB)(void);			 								// 初始化FLASH设备
    void (*readFlashCB)(uint32_t addr, uint8_t *buf, uint16_t size);		//调用硬件层从FLASH中读取数据
    void (*eraseFlashCB)(uint32_t addr, uint16_t size);					//调用硬件层从FLASH中擦除数据
    void (*writeFlashCB)(uint32_t addr, uint8_t *buf, uint16_t size);		//调用硬件层向FLASH中写入数据
} FlashDevice_t;

/*分区*/
typedef struct {
    FlashDevice_t *partFlash;        // 分区所属的Flash设备
    uint32_t partStartAddr;          // 分区起始地址
    uint16_t partSize;               // 分区尺寸
    uint8_t *dataAddr;               // 默认数据集缓冲区首地址
    uint16_t dataSize;               // 数据集尺寸
    uint16_t pageNum;				 // 分区中存在多少页面
    uint16_t dataNum;				 // 每页中数据区的数量
} Partition_t;

/*页头*/
typedef struct {
        PageStatus_t pageStatus;           						// 页状态
        uint32_t  dataIndex[DATA_INDEX_UNIN_MAX];               // 数据区索引，指向最新的数据区域
} PageHeader_t;

void FML_FlashDeviceRegister(FlashDevice_t *flash);				// 用户注册FLASH
void FML_PartInit(Partition_t *part,uint8_t size);				// 分区初始化
void FML_PartReset(Partition_t *part);							// 重置分区
FLASH_Err_t FML_PartRead(Partition_t Part, uint8_t* buff);		// 根据键值查找分区读取函数
FLASH_Err_t FML_PartWrite(Partition_t Part, uint8_t* buff);		// 向分区内写入数据

#endif /* INC_FML_STORE_H_ */
